Exposing Process State via HTTP 
HyperBEAM enables direct HTTP access to process state, providing efficient data reads for web frontends and data services that need to access process data. This is the standard approach for reading process state in HyperBEAM.
The Patch Device 
The [email protected] device is the mechanism that allows AO processes to make parts of their internal state readable via direct HTTP GET requests.
How Exposing Process State via HTTP Works 
State exposure follows a simple four-step pattern:
- Process Logic: From your process (e.g., in Lua or WASM), send an outbound message to the [email protected]device.
- Patch Message Format: The message must include the devicetag and data to expose.luaSend({ Target = ao.id, device = '[email protected]', mydatakey = MyValue })
- HyperBEAM Execution: HyperBEAM's dev_patchmodule processes this message, mapping the key-value pairs from thecachetable to a URL path.
- HTTP Access: The exposed data is then immediately available via a standard HTTP GET request to the process's endpoint.HyperBEAMGET /<process-id>[email protected]/compute/<mydatakey>
Initial State Sync 
Make data available immediately on process creation by patching initial state:
Balances = { token1 = 100, token2 = 200 }
TotalSupply = 1984
InitialSync = InitialSync or 'INCOMPLETE'
if InitialSync == 'INCOMPLETE' then
  Send({
    device = '[email protected]',
    balances = Balances,
    totalsupply = TotalSupply
  })
  InitialSync = 'COMPLETE'
  print("Initial state sync complete")
endThis makes essential data queryable upon process creation, boosting responsiveness.
Basic Handler Example 
Expose state when actions occur:
Handlers.add(
  "PublishData",
  Handlers.utils.hasMatchingTag("Action", "PublishData"),
  function(msg)
    local data = "Important state: " .. math.random()
    Send({ device = '[email protected]', currentstatus = data })
    print("Published data to /compute/currentstatus")
  end
)For comprehensive patterns, see Building with HyperBEAM.
Avoiding Key Conflicts 
Keys in the patch message become URL path segments. To avoid conflicts with reserved HyperBEAM paths, use descriptive, specific keys. Avoid using reserved keywords such as:
now, compute, state, info, testFor instance, prefer a key like myappstate over a generic key like state.
WARNING
HTTP paths are case-insensitive. While the patch device stores keys with case sensitivity (e.g., MyKey vs mykey), HTTP access to paths like the following is ambiguous and may lead to unpredictable results.
To prevent conflicts, always use lowercase keys in your patch messages (e.g., mykey, usercount).
  GET /<process-id>[email protected]/compute/mykeyKey Points 
- Path Structure: Data is exposed at a path structured like this, where <key>is a key from your patch message:HyperBEAM/<process-id>[email protected]/compute/<key>
- Data Types: Basic data types like strings and numbers work best. Complex objects may require serialization.
- computevs- now: Accessing exposed data can be done via two main paths:HyperBEAMThe- GET /<process-id>[email protected]/compute/<key> GET /<process-id>[email protected]/now/<key>- computeendpoint serves the last known value quickly, while- nowmay perform additional computation to get the most recent state.
- Read-Only Exposure: State exposure is for efficient reads and does not replace your process's core state management logic.
Using the patch device enables efficient, standard HTTP access to your process state, seamlessly connecting decentralized logic with web applications.
Patching User-Owned Processes 
If your application spawns processes owned by users, you need to provide ways for them to enable state patching since only process owners can update their processes.
Common Scenarios 
- Marketplace Applications: Each vendor manages their own inventory process
- User Vaults: Personal processes for storing data or assets
- Decentralized Applications: Users spawn game characters, agents, or bots
- Token Pairs: DEX applications with user-created trading pair processes
Implementation 
1. Enable State Patching 
Add a handler to enable patching and sync current state:
Handlers.add(
  "EnableStatePatch",
  Handlers.utils.hasMatchingTag("Action", "EnableStatePatch"),
  function(msg)
    if msg.From ~= ao.id then return end
    -- Sync current state
    Send({
      device = '[email protected]',
      balances = Balances,
      -- ... other state
    })
    -- Set flag to enable auto-patching in other handlers
    StatePatchEnabled = true
  end
)2. Update Existing Handlers 
Modify existing handlers to automatically expose state when it changes:
-- Before: Simple transfer handler
Handlers.add(
  "Transfer",
  Handlers.utils.hasMatchingTag("Action", "Transfer"),
  function(msg)
    -- Transfer logic
    Balances[msg.From] = (Balances[msg.From] or 0) - msg.Quantity
    Balances[msg.Target] = (Balances[msg.Target] or 0) + msg.Quantity
  end
)
-- After: Transfer handler with state exposure
Handlers.add(
  "Transfer",
  Handlers.utils.hasMatchingTag("Action", "Transfer"),
  function(msg)
    -- Transfer logic
    Balances[msg.From] = (Balances[msg.From] or 0) - msg.Quantity
    Balances[msg.Target] = (Balances[msg.Target] or 0) + msg.Quantity
    -- Auto-expose state if patching is enabled
    if StatePatchEnabled then
      Send({ device = '[email protected]', balances = Balances })
    end
  end
)3. Detection & Triggering 
// Check if patching is enabled
async function isPatchEnabled(processId) {
  try {
    const response = await fetch(
      `https://forward.computer/${processId}[email protected]/compute/balances`,
      { method: "HEAD" },
    );
    return response.ok;
  } catch {
    return false;
  }
}
// User enables patching
import { message, createDataItemSigner } from "@permaweb/aoconnect";
await message({
  process: userProcessId,
  signer: createDataItemSigner(window.arweaveWallet),
  tags: [{ name: "Action", value: "EnableStatePatch" }],
});This approach maintains user ownership while ensuring state stays synchronized automatically.
Next Steps 
With state exposure configured, you can now add dynamic reads to compute values on-the-fly without modifying your process state.